﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LunarSF.SHomeWorkshop.LunarMind
{
    /**
 * 由BaseQuestion拆分而成，如果一个Base中只有一个填充项，则会被拆分成一个Question。
 * BaseQuestion的Body（题干）中有几个填空项，就应该有几个答案列表。
 *
 * @author YangZhenyv
 */
    public class Question
    {
        private List<ChoiceItem> choiceItems = new List<ChoiceItem>();

        public List<ChoiceItem> ChoiceItems
        {
            get { return this.choiceItems; }
        }

        private string answer = string.Empty;
        /// <summary>
        /// [只读]仅适用于选择题（包括判断题）、填空题。不适用于主观题。
        /// </summary>
        public string Answer
        {
            get
            {
                if (choiceItems.Count <= 0)
                {
                    if (string.IsNullOrEmpty(this.titleString)) return string.Empty;

                    //填空题
                    int startBracket = this.titleString.IndexOf("【");
                    int closeBracket = this.titleString.IndexOf("】");

                    if (startBracket < 0 || closeBracket < 0 || closeBracket < startBracket) return string.Empty;

                    return this.titleString.Substring(startBracket, closeBracket - startBracket);
                }

                return this.answer;
            }
        }

        public Question(string titleString)
        {
            this.titleString = titleString;
        }

        /// <summary>
        /// [构造方法]生成一道试题。适用于填空题（无答案）、选择题（有答案项、错项，）、判断题（特殊的选择题）。
        /// </summary>
        /// <param name="titleString">应传入由BaseQuestion.BuildQuestionTitles()方法生成的String[]的某个成员。
        /// 它的形式是一行带一个填空的文本。</param>
        /// <param name="bodyString">应传入每个试题的原文本的“答案”部分，
        /// 每个答案文本片段中应包含一个“答案”及一个或多个“错项”。</param>
        public Question(string titleString, string bodyString)
        {
            this.titleString = titleString;

            if (string.IsNullOrEmpty(bodyString)) return;//填空题，有填充项而无答案项。

            // 根据bodyStrings生成BaseQuestionItems
            String[] itemStrings = bodyString.Split(new string[1] { "错项＞＞" }, StringSplitOptions.None);
            // 第一个片段是答案，其余每个片段都是“错项”。

            if (itemStrings.Length > 1)
            {
                ChoiceItem answerChoiceItem = new ChoiceItem();
                answerChoiceItem.IsAnswer = true;

                int indexOfAnalysis = itemStrings[0].IndexOf("解析＞＞");
                if (indexOfAnalysis > -1)
                {
                    answerChoiceItem.Text = itemStrings[0].Substring(0, indexOfAnalysis);
                    answerChoiceItem.AnalysisText = L.formatChoiceQuestionTextString(itemStrings[0].Substring(indexOfAnalysis + 4));
                }
                else
                {
                    answerChoiceItem.Text = itemStrings[0];
                }

                this.choiceItems.Add(answerChoiceItem);
                this.answer = answerChoiceItem.Text;

                for (int ii = 1; ii < itemStrings.Length; ii++)
                {
                    ChoiceItem otherChoiceItem = new ChoiceItem();

                    indexOfAnalysis = -1;
                    // 索引从1开始。
                    indexOfAnalysis = itemStrings[ii].IndexOf("解析＞＞");
                    if (indexOfAnalysis > -1)
                    {
                        otherChoiceItem.Text = L.formatChoiceQuestionTextString(itemStrings[ii].Substring(0, indexOfAnalysis));

                        otherChoiceItem.AnalysisText = L.formatChoiceQuestionTextString(itemStrings[ii].Substring(indexOfAnalysis + 4));
                    }
                    else
                    {
                        otherChoiceItem.Text = L.formatChoiceQuestionTextString(itemStrings[ii]);
                    }

                    this.choiceItems.Add(otherChoiceItem);
                }
            }

            // 使用随机数混淆顺序。
            int[] random = L.getRandomIntArray(choiceItems.Count);
            foreach (int i in random)
            {
                choiceItems[i].OrderNumber = random[i];
            }
        }

        /// <summary>
        /// [构造方法]适用于
        /// </summary>
        /// <param name="titleString"></param>
        /// <param name="titleAndAnswers"></param>
        public Question(string titleString, string[] titleAndAnswers)
        {
            this.titleString = titleString;

            this.answers.Clear();
            for (int i = 1; i < titleAndAnswers.Length; i++)
            {
                this.answers.Add(titleAndAnswers[i]);
            }
        }

        public QuestionType Type
        {
            get
            {
                if (this.choiceItems.Count <= 0)
                {
                    if (this.answers.Count > 0) return QuestionType.Subjective;
                    return QuestionType.FillBlank;
                }
                else
                {
                    //判断题是只有两个选项的选择题，且两个选项必须是：一个“正确”、一个“错误”。
                    if (this.choiceItems.Count == 2)
                    {
                        if ((this.choiceItems[0].Text == "正确" && this.choiceItems[1].Text == "错误") ||
                            (this.choiceItems[0].Text == "错误" && this.choiceItems[1].Text == "正确")) return QuestionType.Judge;
                    }
                    return QuestionType.Choice;
                }
            }
        }


        #region 主观题使用的几个列表。

        private List<string> materials = new List<string>();

        public List<string> Materials { get { return this.materials; } }

        private List<string> asksList = new List<string>();

        public List<string> AsksList { get { return this.asksList; } }

        private List<string> answers = new List<string>();
        /// <summary>
        /// [只读]此属性仅适用于主观题。
        /// </summary>
        public List<string> Answers { get { return this.answers; } }

        #endregion
        
        
        private string titleString;

        public string TitleString
        {
            get
            {
                return titleString;
            }
            set
            {
                this.titleString = value;
            }
        }

        public int OrderNumber
        {
            get
            {
                return orderNumber;
            }
            set
            {
                this.orderNumber = value;
            }
        }

        private int orderNumber = 0;
    }

    public enum QuestionType { Choice, FillBlank, Judge, Subjective }
}
